package fun.yao.common.msg;

import fun.yao.common.Constant;
import fun.yao.common.uitls.CommonUtil;
import fun.yao.common.uitls.MsgUtil;

/**
 * 交易类请求报文（包括报文头和报文体）
 */
public class TransReqMsg {
    //------------------------- 报文头报文长度定义
    public final static int SEQ_NO_LEN = 8;
    public final static int MSG_TYPE_LEN = 1;
    public final static int EXCH_CODE_LEN = 4;
    public final static int MSG_FLAG_LEN = 1;
    public final static int TERM_TYPE_LEN = 2;
    public final static int USER_TYPE_LEN = 2;
    public final static int USER_ID_LEN = 10;
    public final static int AREA_CODE_LEN = 4;
    public final static int BRANCH_ID_LEN = 12;
    public final static int C_TELLER_ID1 = 10;
    public final static int C_TELLER_ID2 = 10;
    public final static int SESSION_ID_LEN = 16;

    //------------------------- 报文头部分
    /**
     * 流水号
     */
    public String seq_no = "";
    /**
     * 报文类型
     */
    public String msg_type = "";
    /**
     * 交易代码
     */
    public String exch_code = "";
    /**
     * 报文标识
     */
    public String msg_flag = "";
    /**
     * 终端来源
     */
    public String term_type = "";
    /**
     * 用户类型
     */
    public String user_type = "";
    /**
     * 用户ID
     */
    public String user_id = "";
    /**
     * 地区代码
     */
    public String area_code = "";
    /**
     * 代理机构
     */
    public String branch_id = "";
    /**
     * 一级复核操作员
     */
    public String c_teller_id1 = "";
    /**
     * 二级复核操作员
     */
    public String c_teller_id2 = "";
    /**
     * Session Id
     */
    public String session_id = "";

    //------------------------- 报文体
    public final StringBuffer sbMsgBody = new StringBuffer();

    //原始报文
    public String sSrcReqMsg = "";

    /**
     * 操作代码
     */
    public String oper_flag = "";

    /**
     * 流水号(可能为空，不为空时可使用该流水号记入到业务流水表中)
     */
    public String serial_no = "";

    /**
     * 对象生成时间 add by csl 2011.3.22
     */
    protected long sStartTime = System.currentTimeMillis();

    /**
     * 报文头类型 为区分二级系统老报文头
     */
    public boolean is_new = true;

    /**
     * 解析请求报文
     *
     * @param sReqMsg
     */
    public void Parse(String sReqMsg) {
        //通过报文头长度兼容老报文
        if (sReqMsg.indexOf(Constant.MSG_SEPARATOR_FIELD) < 80)
            this.is_new = false;

        int index = 0;
        seq_no = sReqMsg.substring(index, index + SEQ_NO_LEN).trim();
        index += SEQ_NO_LEN;
        msg_type = sReqMsg.substring(index, index + MSG_TYPE_LEN).trim();
        index += MSG_TYPE_LEN;
        exch_code = sReqMsg.substring(index, index + EXCH_CODE_LEN).trim();
        index += EXCH_CODE_LEN;
        msg_flag = sReqMsg.substring(index, index + MSG_FLAG_LEN).trim();
        index += MSG_FLAG_LEN;
        term_type = sReqMsg.substring(index, index + TERM_TYPE_LEN).trim();
        index += TERM_TYPE_LEN;
        user_type = sReqMsg.substring(index, index + USER_TYPE_LEN).trim();
        index += USER_TYPE_LEN;
        user_id = sReqMsg.substring(index, index + USER_ID_LEN).trim();
        index += USER_ID_LEN;
        area_code = sReqMsg.substring(index, index + AREA_CODE_LEN).trim();
        index += AREA_CODE_LEN;
        branch_id = sReqMsg.substring(index, index + BRANCH_ID_LEN).trim();
        index += BRANCH_ID_LEN;
        c_teller_id1 = sReqMsg.substring(index, index + C_TELLER_ID1).trim();
        index += C_TELLER_ID1;
        c_teller_id2 = sReqMsg.substring(index, index + C_TELLER_ID2).trim();
        index += C_TELLER_ID2;

        if (is_new) {
            session_id = sReqMsg.substring(index, index + SESSION_ID_LEN).trim();
            index += SESSION_ID_LEN;
        } else {
            session_id = c_teller_id2;
        }


        sbMsgBody.append(sReqMsg.substring(index).trim());

        oper_flag = MsgUtil.getMsgFieldValue(sReqMsg, "oper_flag");

        sSrcReqMsg = sReqMsg;
    }

    /**
     * 获得请求报文的唯一值
     *
     * @return
     */
    public String getUniqueKey() {
        StringBuffer sb = new StringBuffer(30);
        sb.append(this.user_type);
        sb.append(":");
        sb.append(this.user_id);
        sb.append(":");
        sb.append(this.seq_no);
        return sb.toString();
    }

    /**
     * 拼组请求报文字符串
     */
    public String toString() {
        //如果为老报文,则使用c_teller_id2字段当成session_id
        if (is_new == false) {

            if (session_id.length() >= C_TELLER_ID2)
                this.c_teller_id2 = session_id.substring(0, C_TELLER_ID2);

        }
        StringBuffer sb = new StringBuffer();
        sb.append(CommonUtil.FILL(seq_no, ' ', SEQ_NO_LEN, 'R'));
        sb.append(CommonUtil.FILL(msg_type, ' ', MSG_TYPE_LEN, 'R'));
        sb.append(CommonUtil.FILL(exch_code, ' ', EXCH_CODE_LEN, 'R'));
        sb.append(CommonUtil.FILL(msg_flag, ' ', MSG_FLAG_LEN, 'R'));
        sb.append(CommonUtil.FILL(term_type, ' ', TERM_TYPE_LEN, 'R'));
        sb.append(CommonUtil.FILL(user_type, ' ', USER_TYPE_LEN, 'R'));
        sb.append(CommonUtil.FILL(user_id, ' ', USER_ID_LEN, 'R'));
        sb.append(CommonUtil.FILL(area_code, ' ', AREA_CODE_LEN, 'R'));
        sb.append(CommonUtil.FILL(branch_id, ' ', BRANCH_ID_LEN, 'R'));
        sb.append(CommonUtil.FILL(c_teller_id1, ' ', C_TELLER_ID1, 'R'));
        sb.append(CommonUtil.FILL(c_teller_id2, ' ', C_TELLER_ID2, 'R'));
        if (is_new) {
            sb.append(CommonUtil.FILL(session_id, ' ', SESSION_ID_LEN, 'R'));
        }

        //add by ljl 20190516，增加报文体分隔符
        if (sbMsgBody.toString().startsWith(Constant.MSG_SEPARATOR_FIELD + "") == false) {
            sb.append(Constant.MSG_SEPARATOR_FIELD);
        }

        sb.append(sbMsgBody.toString());

        return sb.toString();
    }

    /**
     * 获得处理时间（毫秒） add by csl 2011.3.22
     *
     * @return
     */
    public long getDealTime() {
        return System.currentTimeMillis() - sStartTime;
    }

    /**
     * 获取开始时间
     * add by ljl 20161123
     *
     * @return
     */
    public long getStartTime() {
        return sStartTime;
    }

    /**
     * 拷贝对象
     *
     * @param srcTReq
     */
    public void copy(TransReqMsg srcTReq) {
        this.area_code = srcTReq.area_code;
        this.branch_id = srcTReq.branch_id;
        this.c_teller_id1 = srcTReq.c_teller_id1;
        this.c_teller_id2 = srcTReq.c_teller_id2;
        this.msg_flag = srcTReq.msg_flag;
        this.msg_type = srcTReq.msg_type;
        this.seq_no = srcTReq.seq_no;
        this.serial_no = srcTReq.serial_no;
        this.term_type = srcTReq.term_type;
        this.user_id = srcTReq.user_id;
        this.user_type = srcTReq.user_type;
        this.session_id = srcTReq.session_id;
    }
}
